package com.yanqu.road.server.gameplayer.module.activity.suoyao;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.suoyao.SuoYaoChooseRewardData;
import com.yanqu.road.entity.activity.suoyao.SuoYaoHasGetRewardData;
import com.yanqu.road.entity.activity.suoyao.SuoYaoUserData;
import com.yanqu.road.entity.activity.suoyao.config.*;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.log.LogSuoYaoExplore;
import com.yanqu.road.logic.bussiness.activity.SuoYaoBusiness;
import com.yanqu.road.pb.activity.SuoYaoActivityProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.gameplayer.module.player.PreReduceModule;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.suoyao.SuoYaoMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.pb.PlayerPb;
import com.yanqu.road.server.pb.SuoYaoPb;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;


public class SuoYaoModule extends GeneralModule {

    private SuoYaoUserData userData;

    private static Logger logger = LogManager.getLogger(SuoYaoModule.class.getName());

    public SuoYaoModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        ActivityInfo activityInfo = SuoYaoMgr.getActivityInfo();
        if (ActivityMgr.activityInShowTime(activityInfo)) {
            userData = SuoYaoBusiness.getSuoYaoUserData(activityInfo.getActivityId(), player.getUserId());
            initUserData();
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        if (userData != null) {
            if (userData.isInsertOption()) {
                SuoYaoBusiness.addSuoYaoUserData(userData);
            } else if (userData.isUpdateOption()) {
                SuoYaoBusiness.updateSuoYaoUserData(userData);
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        checkBox();
        checkFloorUp();

        syncSuoYaoConfig();
        syncUserData();
    }

    public void syncSuoYaoConfig() {
        SuoYaoConfig suoYaoConfig = SuoYaoMgr.getSuoYaoConfig();
        if (suoYaoConfig != null) {
            SuoYaoActivityProto.SyncSuoYaoConfigRespMsg.Builder builder = SuoYaoActivityProto.SyncSuoYaoConfigRespMsg.newBuilder();
            builder.setConfig(SuoYaoPb.parseSuoYaoConfigMsg(suoYaoConfig, player.getLanguage()));
            player.sendPacket(ClientProtocol.U_SUOYAO_ACTIVITY_SYNC_CONFIG, builder);
        }
    }

    public void syncUserData() {
        if (userData != null) {
            SuoYaoActivityProto.SyncSuoYaoUserDataRespMsg.Builder builder = SuoYaoActivityProto.SyncSuoYaoUserDataRespMsg.newBuilder();
            builder.setUserData(SuoYaoPb.parseSuoYaoUserDataMsg(userData));
            player.sendPacket(ClientProtocol.U_SUOYAO_ACTIVITY_SYNC_USER_DATA, builder);
        }
    }

    public synchronized void initUserData() {
        // 系统未解锁
        if (!SystemOpenMgr.systemOpen(player, eSystemId.SuoYaoActivity.getValue())) {
            return;
        }
        // 没有活动
        SuoYaoConfig suoYaoConfig = SuoYaoMgr.getSuoYaoConfig();
        if (suoYaoConfig == null || !ActivityMgr.activityInShowTime(suoYaoConfig.getActivityInfo())) {
            return;
        }
        // 已经有数据了
        if (userData != null && userData.getActivityId() == suoYaoConfig.getActivityId()) {
            return;
        }
        userData = new SuoYaoUserData();
        userData.setActivityId(suoYaoConfig.getActivityId());
        userData.setUserId(player.getUserId());
        userData.setFloorNo(1);
        userData.setRewardIdList(new ArrayList<>());
        userData.setScore(0);
        userData.setSwordValue(0);
        userData.setDrawBoxMap(new ConcurrentHashMap<>());
        userData.setTotalTimes(0);
        userData.setCommonTimes(0);
        userData.setLowHideTimes(0);
        userData.setChooseRewardData(new SuoYaoChooseRewardData());
        userData.setHasGetRewardData(new ConcurrentHashMap<>());
        userData.setHasGetBookRewardList(new ArrayList<>());
        userData.setRound(1);

        userData.setInsertOption();
    }

    public SuoYaoUserData getUserData() {
        return userData;
    }

    /**
     * 探宝
     *
     * @param isFast 是否快速探宝
     * @return 错误码
     */
    public int exploreTreasure(boolean isFast) {
        if (userData == null) {
            return GameErrorCode.E_SUOYAO_ACTIVITY_NO_UNLOCK;
        }
        SuoYaoConfig suoYaoConfig = SuoYaoMgr.getSuoYaoConfig();
        if (suoYaoConfig == null) {
            return GameErrorCode.E_SUOYAO_ACTIVITY_NO_OPEN;
        }
        if (!ActivityMgr.activityInTimeAndShowTime(suoYaoConfig.getActivityInfo())){
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }


        SuoYaoChooseRewardData chooseRewardData = userData.getChooseRewardData();
        if (chooseRewardData.getRewardId()<=0){
            return GameErrorCode.E_SUO_YAO_NO_CHOOSE_TOP_REWARD;
        }
        if (chooseRewardData.getIndex()<0){
            return GameErrorCode.E_SUO_YAO_NO_CHOOSE_TOP_REWARD;
        }
        SuoYaoTopRewardConfig topRewardConfig = SuoYaoMgr.getTopRewardConfig(chooseRewardData.getRewardId());
        if (topRewardConfig == null){
            return GameErrorCode.E_SUOYAO_CHOOSE_REWARD_PARAM_ERROR;
        }

        boolean isSelected = chooseRewardData.isSelected();
        int userGetTopRewardTime = getUserGetTopRewardTime(chooseRewardData.getRewardId(),chooseRewardData.getIndex(), isSelected);
        int maxTime = isSelected ? topRewardConfig.getSelectedTime() : topRewardConfig.getRewardLimit().get(chooseRewardData.getIndex());
        if (userGetTopRewardTime >= maxTime){
            return GameErrorCode.E_SUOYAO_CHOOSE_TOP_REWARD_TIME_MAX;
        }

        Map<Integer, Map<Integer, SuoYaoRewardConfig>> floorMap = suoYaoConfig.getFloorMap();
        Random random = new Random();

        // 开始探宝
        List<Integer> rewardIdList = new ArrayList<>();
        List<String> rewardList = new ArrayList<>();

        for (int times = 0; times < 100; times++) {

            // 非快速探宝只抽一次
            if (!isFast && rewardIdList.size() >= 1) {
                break;
            }

            // 获取未抽奖励
            Map<Integer, SuoYaoRewardConfig> floorConfig = floorMap.get(userData.getFloorNo());
            List<Integer> noGetList = new ArrayList<>();
            List<Integer> weightList = new ArrayList<>();
            for (SuoYaoRewardConfig rewardConfig : floorConfig.values()) {
                if (!userData.getRewardIdList().contains(rewardConfig.getRewardId())) {
                    noGetList.add(rewardConfig.getRewardId());
                    weightList.add(rewardConfig.getWeight());
                }
            }

            // 抽
            int index = RandomHelper.getRandomIndexByWeight(weightList, random);
            Integer rewardId = noGetList.get(index);

            // 扣消耗
            Property property = new Property();
            int needCostNum = suoYaoConfig.getExploreCountList().get(userData.getFloorNo() - 1);
            property.addProperty(suoYaoConfig.getExploreItemId(),
                    BigInteger.valueOf(needCostNum));
            if (!player.getModule(CurrencyModule.class).removeCurrency(property, eLogMoneyType.SuoYaoActivity, eLogMoneyType.SuoYaoActivityExploreCost)) {
                break;
            }
            //新的成就 使用道具数量
            player.notifyListener(eGamePlayerEventType.SuoYaoExploreItemUse.getValue(), needCostNum);
            // 先加抽到的第一个奖励
            SuoYaoRewardConfig rewardConfig = floorConfig.get(rewardId);
            Property reward = new Property();
            if (rewardConfig.getReward().equals("0")){
                String topReward = SuoYaoMgr.getTopReward(chooseRewardData.getRewardId(), chooseRewardData.getIndex(), isSelected);
                addGetTopRewardTime(chooseRewardData.getRewardId(),chooseRewardData.getIndex(), isSelected);
                reward.addProperty(PropertyHelper.parseStringToProperty(topReward));

            }else {
                reward = PropertyHelper.parseStringToProperty(rewardConfig.getReward());
            }
            // 记录抽中的奖
            rewardIdList.add(rewardId);
            rewardList.add(PropertyHelper.parsePropertyToString(reward));
            userData.getRewardIdList().add(rewardId);

            //7.1新增 如果是大奖 要把其他没拿到的小奖一起给了
            if (rewardConfig.isBigReward()){
                if (noGetList.size()>1){
                    for (int noGetId : noGetList){
                        if (noGetId == rewardConfig.getRewardId()){
                            continue;
                        }else {
                            SuoYaoRewardConfig noGetConfig = floorConfig.get(noGetId);
                            Property otherReward = PropertyHelper.parseStringToProperty(noGetConfig.getReward());
                            reward.addProperty(otherReward);

                            rewardList.add(noGetConfig.getReward());
                            rewardIdList.add(noGetId);

                            userData.getRewardIdList().add(noGetId);
                        }
                    }
                }
            }

            reward.addProperty(suoYaoConfig.getScoreItemId(), BigInteger.valueOf(rewardConfig.getScore()));

            //只有在开启期间更新积分
            if (ActivityMgr.activityInTime(suoYaoConfig.getActivityInfo())){
                userData.setScore(userData.getScore() + rewardConfig.getScore());
            }

            userData.setUpdateOption();


            // 成就
            player.notifyListener(eGamePlayerEventType.SuoYaoScoreRank.getValue(), userData.getScore());

            //奖励进背包
            player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.SuoYaoActivity, eLogMoneyType.SuoYaoActivityExploreGet);



            // 日志
            AutoLogMgr.add(new LogSuoYaoExplore(
                    suoYaoConfig.getActivityId(),
                    player.getUserId(),
                    userData.getFloorNo(),
                    PropertyHelper.parsePropertyToString(property),
                    PropertyHelper.parsePropertyToString(reward),
                    rewardConfig.getScore(),
                    rewardConfig.isBigReward()
            ));

            // 看看是不是到下一轮了
            checkFloorUp();
            if (userData.getFloorNo() == 1 && userData.getRewardIdList().isEmpty()) {
                break;
            }
        }

        // 一次也没抽就是道具不足
        if (rewardIdList.isEmpty()) {
            return GameErrorCode.E_SUOYAO_ACTIVITY_ITEM_NO_ENOUGH;
        }

        SuoYaoActivityProto.SuoYaoExploreRespMsg.Builder builder = SuoYaoActivityProto.SuoYaoExploreRespMsg.newBuilder();
        builder.setRet(0);
        builder.addAllGetRewardIdList(rewardIdList);
        builder.addAllReward(rewardList);
        builder.setUserData(SuoYaoPb.parseSuoYaoUserDataMsg(userData));
        player.sendPacket(ClientProtocol.U_SUOYAO_ACTIVITY_EXPLORE_TREASURE, builder);
        return 0;
    }

    /**
     * 抽盲盒
     */
    public int drawBox(int drawIndex) {
        int ret = checkCanDrawBox(drawIndex);
        if (ret != 0) {
            return ret;
        }

        SuoYaoConfig suoYaoConfig = SuoYaoMgr.getSuoYaoConfig();

        // 超出低价范围：正常抽
        if (userData.getTotalTimes() > suoYaoConfig.getHideBoxTimes()) {
            return drawBoxCore(drawIndex, 1);
        }

        // 低价范围内，中过幸运隐藏款：正常抽
        if (userData.getLowHideTimes() > 0) {
            return drawBoxCore(drawIndex, 1);
        }

        // 低价范围内，没中过幸运隐藏款：判断能不能中幸运隐藏款
        boolean hide = new Random().nextInt(1000) < suoYaoConfig.getLuckyPercent();
        if (hide) {
            // 跨服再次判断
            userData.setLastDrawHideTime(System.currentTimeMillis());
            SuoYaoActivityProto.CrossSuoYaoDrawHideBoxReqMsg.Builder builder = SuoYaoActivityProto.CrossSuoYaoDrawHideBoxReqMsg.newBuilder();
            builder.setActivityId(suoYaoConfig.getActivityId());
            builder.setCost(suoYaoConfig.getDrawBoxCost());
            builder.setServerId(player.getUserInfo().getOriginalServerId());
            builder.setDrawIndex(drawIndex);
            player.sendPacket(CrossProtocol.C2_SUOYAO_ACTIVITY_DRAW_HIDE_BOX, builder);
            return 0;
        } else {
            // 没中幸运隐藏款：正常抽
            return drawBoxCore(drawIndex, 1);
        }

    }

    /**
     * 抽低价隐藏盲盒跨服返回
     *
     * @param canHide 能否抽到低价隐藏盲盒
     */
    public int drawBoxFromCross(int ret, String cost, boolean canHide, int drawIndex) {
        // 返还预扣除
        player.getModule(PreReduceModule.class).restorePreReduce(cost);
        // 解锁下标
        userData.setLastDrawHideTime(0L);

        if (ret != 0) {
            return ret;
        }

        ret = checkCanDrawBox(drawIndex);
        if (ret != 0) {
            return ret;
        }

        if (canHide) {
            // 跨服判断能抽到隐藏款
            return drawBoxCore(drawIndex, 2);
        } else {
            return drawBoxCore(drawIndex, 1);
        }
    }

    /**
     * 抽盲盒处理逻辑
     *
     * @param drawType 1正常抽，2必定隐藏（低价隐藏专用），3必定非隐藏（暂时没用了）
     */
    private int drawBoxCore(int drawIndex, int drawType) {
        SuoYaoConfig suoYaoConfig = SuoYaoMgr.getSuoYaoConfig();
        if (suoYaoConfig == null) {
            return GameErrorCode.E_SUOYAO_ACTIVITY_NO_OPEN;
        }
        if (userData == null) {
            return GameErrorCode.E_SUOYAO_ACTIVITY_NO_UNLOCK;
        }

        // 抽一个
        SuoYaoBoxItemConfig boxItemConfig;
        switch (drawType) {
            case 1:
                boxItemConfig = SuoYaoMgr.drawBox(userData.getCommonTimes());
                break;
            case 2:
                boxItemConfig = SuoYaoMgr.drawBoxByHide(true);
                break;
            case 3:
                boxItemConfig = SuoYaoMgr.drawBoxByHide(false);
                break;
            default:
                logger.error("SuoYaoModule drawBoxCore drawType error! userId={}", player.getUserId());
                return GameErrorCode.E_SUOYAO_ACTIVITY_NO_OPEN;
        }

        // 扣消耗
        if (!player.getModule(CurrencyModule.class).removeCurrency(PropertyHelper.parseStringToProperty(suoYaoConfig.getDrawBoxCost()), eLogMoneyType.SuoYaoActivity, eLogMoneyType.SuoYaoActivityDrawCost)) {
            return GameErrorCode.E_SUOYAO_ACTIVITY_ITEM_NO_ENOUGH;
        }

        // 修改数据
        userData.setTotalTimes(userData.getTotalTimes() + 1);
        if (boxItemConfig.isHide()) {
            userData.setCommonTimes(0); // 清空加成值
            if (userData.getTotalTimes() <= suoYaoConfig.getHideBoxTimes() && drawType == 2) {
                userData.setLowHideTimes(userData.getLowHideTimes() + 1); // 记录低价隐藏款次数
            }
        } else {
            if (userData.getTotalTimes() > suoYaoConfig.getHideBoxAddTimes()) {
                userData.setCommonTimes(boxItemConfig.isHide() ? 0 : userData.getCommonTimes() + 1); // 超过一定次数才有加成值
            }
        }
        userData.getDrawBoxMap().put(drawIndex, boxItemConfig.getGoodsId());
        userData.setUpdateOption();

        // 加奖励
        String reward = boxItemConfig.getGoodsId() + "=1";
        player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.SuoYaoActivity, eLogMoneyType.SuoYaoActivityDrawGet);

        if (drawType == 2) {
            logger.info("SuoYaoModule：活动ID={}，玩家ID={}，第{}次抽盲盒, 抽到低价隐藏盲盒。奖励：{}", userData.getActivityId(), userData.getUserId(), userData.getTotalTimes(), boxItemConfig.getGoodsId());
        }

        // 上公告
        SuoYaoActivityProto.CrossSuoYaoUploadNoticeReqMsg.Builder noticeBuilder = SuoYaoActivityProto.CrossSuoYaoUploadNoticeReqMsg.newBuilder();
        noticeBuilder.setActivityId(suoYaoConfig.getActivityId());
        noticeBuilder.setPlayer(PlayerPb.parsePlayerBaseTempMsg(player.getUserInfo()));
        noticeBuilder.setGoodsId(boxItemConfig.getGoodsId());
        noticeBuilder.setType(boxItemConfig.isHide() ? 1 : 2); // 1隐藏款，2普通
        player.sendPacket(CrossProtocol.C2_SUOYAO_ACTIVITY_UPLOAD_NOTICE, noticeBuilder);

        checkBox();

        // 返回
        SuoYaoActivityProto.SuoYaoDrawBoxRespMsg.Builder builder = SuoYaoActivityProto.SuoYaoDrawBoxRespMsg.newBuilder();
        builder.setRet(0);
        builder.setReward(reward);
        for (Map.Entry<Integer, Integer> entry : userData.getDrawBoxMap().entrySet()) {
            builder.addBoxData(SuoYaoPb.parseSuoYaoBoxItemMsg(entry.getKey(), entry.getValue()));
        }
        player.sendPacket(ClientProtocol.U_SUOYAO_ACTIVITY_DRAW_BOX, builder);
        return 0;
    }

    /**
     * 判断能否抽盲盒
     *
     * @return 错误码
     */
    public int checkCanDrawBox(int drawIndex) {
        if (userData == null) {
            return GameErrorCode.E_SUOYAO_ACTIVITY_NO_UNLOCK;
        }
        SuoYaoConfig suoYaoConfig = SuoYaoMgr.getSuoYaoConfig();
        if (suoYaoConfig == null) {
            return GameErrorCode.E_SUOYAO_ACTIVITY_NO_OPEN;
        }
        // 道具是否足够
        Property cost = PropertyHelper.parseStringToProperty(suoYaoConfig.getDrawBoxCost());
        if (!player.getModule(CurrencyModule.class).currencyIsEnough(cost)) {
            return GameErrorCode.E_SUOYAO_ACTIVITY_ITEM_NO_ENOUGH;
        }
        // 格子是否被抽取
        if (userData.getDrawBoxMap().containsKey(drawIndex)) {
            return GameErrorCode.E_SUOYAO_ACTIVITY_BOX_HAD_DRAW;
        }
        long now = System.currentTimeMillis();
        if (now - userData.getLastDrawHideTime() < 3000) {
            return GameErrorCode.E_SUOYAO_ACTIVITY_BOX_OPEN_FREQUENTLY;
        }
        return 0;
    }

    /**
     * 检查楼层变化
     */
    public void checkFloorUp() {
        if (userData == null) {
            return;
        }
        SuoYaoConfig suoYaoConfig = SuoYaoMgr.getSuoYaoConfig();
        if (suoYaoConfig == null) {
            return;
        }

        Map<Integer, Map<Integer, SuoYaoRewardConfig>> floorMap = suoYaoConfig.getFloorMap();
        Map<Integer, SuoYaoRewardConfig> floorConfig = floorMap.get(userData.getFloorNo());

        // 还有未抽到的大奖，无法进入下一层
        for (SuoYaoRewardConfig rewardConfig : floorConfig.values()) {
            if (rewardConfig.isBigReward() && !userData.getRewardIdList().contains(rewardConfig.getRewardId())) {
                return;
            }
        }

        // 进入下一次层
        if (userData.getFloorNo() == floorMap.size()) {
            userData.setRewardIdList(new ArrayList<>());
            userData.setFloorNo(1);
            //完成一次记录
            userData.addRound();
            //重置选的大奖
            userData.setChooseRewardData(new SuoYaoChooseRewardData());
        } else {
            userData.setFloorNo(userData.getFloorNo() + 1);
        }
    }

    /**
     * 检查盲盒重置
     */
    public void checkBox() {
        if (userData == null) {
            return;
        }
        SuoYaoConfig suoYaoConfig = SuoYaoMgr.getSuoYaoConfig();
        if (suoYaoConfig == null) {
            return;
        }
        Map<Integer, Integer> boxOpenMap = userData.getDrawBoxMap();
        if (boxOpenMap.size() >= suoYaoConfig.getBoxBatchCount()) {
            userData.setDrawBoxMap(new ConcurrentHashMap<>());
            userData.setLastDrawHideTime(0);
        }
    }

    /**
     * 选择任务自选奖励
     */
    public int chooseTaskReward(int rewardId,int index, boolean isSelected){
        if (userData == null) {
            return GameErrorCode.E_SUOYAO_ACTIVITY_NO_UNLOCK;
        }
        SuoYaoConfig suoYaoConfig = SuoYaoMgr.getSuoYaoConfig();
        if (suoYaoConfig == null) {
            return GameErrorCode.E_SUOYAO_ACTIVITY_NO_OPEN;
        }

        if (index == 0&&rewardId == 0){
            SuoYaoChooseRewardData chooseRewardData = userData.getChooseRewardData();
            chooseRewardData.setRewardId(rewardId);
            chooseRewardData.setIndex(index);
            chooseRewardData.setSelected(isSelected);
            userData.setUpdateOption();
            SuoYaoActivityProto.SuoYaoChooseTopRewardRespMsg.Builder builder = SuoYaoActivityProto.SuoYaoChooseTopRewardRespMsg.newBuilder();
            builder.setRet(0);
            builder.setUserData(SuoYaoPb.parseSuoYaoUserDataMsg(userData));

            player.sendPacket(ClientProtocol.U_SUOYAO_CHOOSE_TASK_REWARD,builder);
            return 0;
        }

        if (index<0){
            return GameErrorCode.E_SUOYAO_TOP_CONFIG_CAN_NO_CHOOSE_REWARD;
        }


        SuoYaoTopRewardConfig topTaskConfig = SuoYaoMgr.getTopRewardConfig(rewardId);
        if (topTaskConfig == null){
            log.error("锁妖塔自选任务奖励失败,配置不存在！！");
            return GameErrorCode.E_SUOYAO_TOP_CONFIG_NO_FOUND;
        }

        List<String> rewardList;
        if (isSelected) {
            rewardList = topTaskConfig.getSelectedLimit();
        } else {
            rewardList = topTaskConfig.getRewardList();
        }
        if (rewardList.size() <= index){
            return GameErrorCode.E_SUOYAO_CHOOSE_REWARD_PARAM_ERROR;
        }
        //如果还没达到配置的需求 不给
        if (topTaskConfig.getRound() > userData.getRound()){
            return GameErrorCode.E_SUOYAO_CHOOSE_REWARD_PARAM_ERROR;
        }

        int userGetTopRewardTime = getUserGetTopRewardTime(rewardId, index, isSelected);
        int maxTime = isSelected ? topTaskConfig.getSelectedTime() : topTaskConfig.getRewardLimit().get(index);
        if (userGetTopRewardTime >= maxTime){
            return GameErrorCode.E_SUOYAO_CHOOSE_TOP_REWARD_TIME_MAX;
        }
        SuoYaoChooseRewardData chooseRewardData = userData.getChooseRewardData();
        chooseRewardData.setRewardId(rewardId);
        chooseRewardData.setIndex(index);
        chooseRewardData.setSelected(isSelected);
        userData.setUpdateOption();

        SuoYaoActivityProto.SuoYaoChooseTopRewardRespMsg.Builder builder = SuoYaoActivityProto.SuoYaoChooseTopRewardRespMsg.newBuilder();
        builder.setRet(0);
        builder.setUserData(SuoYaoPb.parseSuoYaoUserDataMsg(userData));

        player.sendPacket(ClientProtocol.U_SUOYAO_CHOOSE_TASK_REWARD,builder);


        return 0;
    }

    public int getUserGetTopRewardTime(int rewardId,int index, boolean isSelected){
        if (rewardId<=0||index<0){
            return Integer.MAX_VALUE;
        }
        if (userData ==null){
            return 0;
        }

        if (isSelected) {
            Map<Integer, SuoYaoHasGetRewardData> hasGetSelectedData = userData.getHasGetSelectedData();
            if (hasGetSelectedData == null){
                userData.setHasGetSelectedData(new ConcurrentHashMap<>());
                hasGetSelectedData = userData.getHasGetSelectedData();
            }
            if (!hasGetSelectedData.containsKey(rewardId)){
                return 0;
            }
            SuoYaoHasGetRewardData rewardData = hasGetSelectedData.get(rewardId);
            Map<Integer, Integer> getRewardTime = rewardData.getGetRewardTime();
            int res = 0;
            for (int time : getRewardTime.values()) { // 自选奖励的次数是合计的
                res += time;
            }
            return res;
        } else {
            Map<Integer, SuoYaoHasGetRewardData> hasGetRewardData = userData.getHasGetRewardData();
            if (hasGetRewardData == null){
                userData.setHasGetRewardData(new ConcurrentHashMap<>());
                hasGetRewardData = userData.getHasGetRewardData();
            }
            if (!hasGetRewardData.containsKey(rewardId)){
                return 0;
            }
            SuoYaoHasGetRewardData rewardData = hasGetRewardData.get(rewardId);
            Map<Integer, Integer> getRewardTime = rewardData.getGetRewardTime();
            return getRewardTime.getOrDefault(index,0);
        }
    }

    public synchronized void addGetTopRewardTime(int rewardId,int index, boolean isSelected){
        if (userData==null){
            log.error("增加获得奖励次数失败,用户数据不存在 ,rewardId{},Index{}, isSelected:{}",rewardId,index, isSelected);
            return;
        }
        if (rewardId<=0||index<0){
            log.error("增加获得奖励次数失败 ,rewardId{},Index{}, isSelected:{}",rewardId,index, isSelected);
            return;
        }

        if (isSelected) {
            Map<Integer, SuoYaoHasGetRewardData> hasGetSelectedData = userData.getHasGetSelectedData();
            if (!hasGetSelectedData.containsKey(rewardId)) {
                SuoYaoHasGetRewardData rewardData = new SuoYaoHasGetRewardData();
                rewardData.setRewardId(rewardId);
                rewardData.setGetRewardTime(new ConcurrentHashMap<>());
                hasGetSelectedData.put(rewardId, rewardData);
                userData.setUpdateOption();
            }
            SuoYaoHasGetRewardData rewardData = hasGetSelectedData.get(rewardId);
            if (rewardData == null) {
                log.error("增加获得奖励次数失败,数据没初始化,rewardId{},Index{}, 是否自选:{}", rewardId, index, isSelected);
                return;
            }
            Map<Integer, Integer> getRewardTime = rewardData.getGetRewardTime();
            getRewardTime.put(index, getRewardTime.getOrDefault(index, 0) + 1);
            userData.setUpdateOption();
        } else {
            Map<Integer, SuoYaoHasGetRewardData> hasGetRewardData = userData.getHasGetRewardData();
            if (!hasGetRewardData.containsKey(rewardId)){
                SuoYaoHasGetRewardData rewardData = new SuoYaoHasGetRewardData();
                rewardData.setRewardId(rewardId);
                rewardData.setGetRewardTime(new ConcurrentHashMap<>());
                hasGetRewardData.put(rewardId,rewardData);
                userData.setUpdateOption();
            }
            SuoYaoHasGetRewardData rewardData = hasGetRewardData.get(rewardId);
            if (rewardData == null){
                log.error("增加获得奖励次数失败,数据没初始化,rewardId{},Index{}",rewardId,index);
                return;
            }
            Map<Integer, Integer> getRewardTime = rewardData.getGetRewardTime();
            getRewardTime.put(index,getRewardTime.getOrDefault(index,0)+1);
            userData.setUpdateOption();
        }
    }

    /**
     * 获取图鉴奖励
     * @param bookId
     * @return
     */

    public int getBookViewReward(int bookId){

        SuoYaoConfig suoYaoConfig = SuoYaoMgr.getSuoYaoConfig();
        if (suoYaoConfig == null) {
            return GameErrorCode.E_SUOYAO_ACTIVITY_NO_OPEN;
        }
        if (userData == null) {
            return GameErrorCode.E_SUOYAO_ACTIVITY_NO_UNLOCK;
        }
        if (!ActivityMgr.activityInTimeAndShowTime(suoYaoConfig.getActivityInfo())){
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }
        SuoYaoViewBookConfig suoYaoViewBookConfig = suoYaoConfig.getViewBookConfigMap().get(bookId);
        if (suoYaoViewBookConfig == null){
            return GameErrorCode.E_SUO_YAO_BOOK_CONFIG_ERROR;
        }
        List<Integer> hasGetBookRewardList = userData.getHasGetBookRewardList();
        if (hasGetBookRewardList.contains(bookId)){
            return GameErrorCode.E_SUO_YAO_REWARD_HAS_GET;
        }
        //  如果没有通关过 就要看看层数了
        if (userData.getRound()<2){
            if (userData.getFloorNo()<suoYaoViewBookConfig.getLayer()){
                return GameErrorCode.E_TASK_NOT_COMPLETE;
            }
        }
        hasGetBookRewardList.add(bookId);
        userData.setUpdateOption();

        player.getModule(CurrencyModule.class).addCurrency(suoYaoViewBookConfig.getViewReward(),eLogMoneyType.SuoYaoActivity,eLogMoneyType.SuoYaoViewBookReward);

        SuoYaoActivityProto.SuoYaoGetBookRewardResp.Builder builder = SuoYaoActivityProto.SuoYaoGetBookRewardResp.newBuilder();
        builder.setRet(0);
        builder.setReward(suoYaoViewBookConfig.getViewReward());
        builder.setData(SuoYaoPb.parseSuoYaoUserDataMsg(userData));

        player.sendPacket(ClientProtocol.U_SUOYAO_GET_BOOK_REWARD,builder);

        return 0;
    }

    /**
     * 测试
     * @return 错误码
     */
    public int exploreTreasureTestOne() {
        int sixNum = 0;
        long totalUse = 0;
        int max = 120;
        int min = 120;

        for (long userId =0;userId < 10000;userId++){

            SuoYaoConfig suoYaoConfig = SuoYaoMgr.getSuoYaoConfig();
            Map<Integer, Map<Integer, SuoYaoRewardConfig>> floorMap = suoYaoConfig.getFloorMap();

            userData = new SuoYaoUserData();
            userData.setActivityId(suoYaoConfig.getActivityId());
            userData.setUserId(player.getUserId());
            userData.setFloorNo(1);
            userData.setRewardIdList(new ArrayList<>());
            userData.setScore(0);
            userData.setSwordValue(0);
            userData.setDrawBoxMap(new ConcurrentHashMap<>());
            userData.setTotalTimes(0);
            userData.setCommonTimes(0);
            userData.setLowHideTimes(0);
            userData.setChooseRewardData(new SuoYaoChooseRewardData());
            userData.setHasGetRewardData(new ConcurrentHashMap<>());
            userData.setHasGetBookRewardList(new ArrayList<>());
            userData.setRound(1);

            Random random = new Random();

            int hasItem = 1000;


            // 开始探宝
            List<String> rewardList = new ArrayList<>();

            Property testTotalReward = new Property();
            int times = 0;
            for (; times < 10000; times++) {

                // 获取未抽奖励
                Map<Integer, SuoYaoRewardConfig> floorConfig = floorMap.get(userData.getFloorNo());
                List<Integer> noGetList = new ArrayList<>();
                List<Integer> weightList = new ArrayList<>();
                for (SuoYaoRewardConfig rewardConfig : floorConfig.values()) {
                    if (!userData.getRewardIdList().contains(rewardConfig.getRewardId())) {
                        noGetList.add(rewardConfig.getRewardId());
                        weightList.add(rewardConfig.getWeight());
                    }
                }

                // 抽
                int index = RandomHelper.getRandomIndexByWeight(weightList, random);
                Integer rewardId = noGetList.get(index);

                // 扣消耗

                int needCostNum = suoYaoConfig.getExploreCountList().get(userData.getFloorNo() - 1);

                if (hasItem < needCostNum) {
                    break;
                }
                hasItem = hasItem - needCostNum;

                // 先加抽到的第一个奖励
                SuoYaoRewardConfig rewardConfig = floorConfig.get(rewardId);
                Property reward = new Property();
                if (rewardConfig.getReward().equals("0")){

                    reward.addProperty(new Property(666,1));

                }else {
                    reward = PropertyHelper.parseStringToProperty(rewardConfig.getReward());
                }
                // 记录抽中的奖

                rewardList.add(PropertyHelper.parsePropertyToString(reward));
                testTotalReward.addProperty(reward);
                userData.getRewardIdList().add(rewardId);

                //7.1新增 如果是大奖 要把其他没拿到的小奖一起给了
                if (rewardConfig.isBigReward()){
                    if (noGetList.size()>1){
                        for (int noGetId : noGetList){
                            if (noGetId == rewardConfig.getRewardId()){
                                continue;
                            }else {
                                SuoYaoRewardConfig noGetConfig = floorConfig.get(noGetId);
                                Property otherReward = PropertyHelper.parseStringToProperty(noGetConfig.getReward());
                                reward.addProperty(otherReward);

                                rewardList.add(noGetConfig.getReward());
                                testTotalReward.addProperty(reward);


                                userData.getRewardIdList().add(noGetId);
                            }
                        }
                    }
                }

                reward.addProperty(suoYaoConfig.getScoreItemId(), BigInteger.valueOf(rewardConfig.getScore()));

                // 看看是不是到下一轮了
                checkFloorUp();
//            if (userData.getFloorNo() == 1 && userData.getRewardIdList().isEmpty()) {
//                break;
//            }
                BigInteger countByGoodsId = testTotalReward.getCountByGoodsId(666);
                if (countByGoodsId.intValue()>=6){
                    break;
                }

            }

            int usenum = 1000 - hasItem;
            if (usenum < min){
                min = usenum;
            }
            if (usenum>max){
                max = usenum;
            }
            BigInteger countByGoodsId = testTotalReward.getCountByGoodsId(666);
            if (userId >= 0){
                System.out.println("玩家编号"+userId+"抽奖次数"+times+" 抽奖结果："+ PropertyHelper.parsePropertyToString(testTotalReward)+"话费道具"+ usenum+"大奖次数"+countByGoodsId.intValue());
            }
            totalUse+= usenum;

        }
        System.out.println("6次中奖次数"+sixNum);
        System.out.println("平均花费"+(double)totalUse/100000);
        System.out.println("最小话费"+min+" 最大话费"+max);

        return 0;
    }

}
